package edu.hawaii.myisern.model;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.After;
import org.junit.Test;

/**
 * Test the DatabaseCollaborations object.
 * 
 * @author Randy Cox
 * 
 */
public class TestDatabaseCollaborations {

  /**
   * Test the dropping and creating of collaboration tables.
   */
  @Test
  public void testCreateDropTable() {
    DatabaseCollaborations db = new DatabaseCollaborations();
    db.createTables();
    assertTrue("Check that collaboration table is there.", db.hasTableCollaborations());
    assertTrue("Check that collaborating organization table is there.", db.hasTableOrganizations());
    db.createTables();
    assertTrue("Check that collaboration table is still there.", db.hasTableCollaborations());
    assertTrue("Check that collaborating organization table is still there.", db
        .hasTableOrganizations());
    db.dropTables();
    assertFalse("Check that collaboration table is gone.", db.hasTableCollaborations());
    assertFalse("Check that collaborating organization table is gone.", db.hasTableOrganizations());
    db.dropTables();
    assertFalse("Check that there is no error.", db.hasTableCollaborations());
    assertFalse("Check that there is no error with sub table.", db.hasTableOrganizations());
  }

  /**
   * Test the insert, update, query etc for the collaboration table.
   */
  @Test
  public void testGetSave() {
    DatabaseCollaborations db = new DatabaseCollaborations();

    // Set up test strings.
    String id = ("COLLABORATION_NAME");
    String name = "collaboration name ";
    String desc = "Desc";
    String[] organizations = { "Organization1", "Organization2", "Organization3" };
    String[] years = { "2000", "2001", "2002" };
    String[] types = { "Type1", "Type2", "Type3" };
    String[] outcomes = { "Outcome1", "Outcome2", "Outcome3" };

    // Set up record vars.
    MyCollaboration collaboration = new MyCollaboration();
    collaboration.setName(name);
    collaboration.setDescription(desc);
    collaboration.addOrganization(organizations[0]);
    collaboration.addOrganization(organizations[1]);
    collaboration.addOrganization(organizations[2]);
    collaboration.addYear(years[0]);
    collaboration.addYear(years[1]);
    collaboration.addYear(years[2]);
    collaboration.addType(types[0]);
    collaboration.addType(types[1]);
    collaboration.addType(types[2]);
    collaboration.addOutcome(outcomes[0]);
    collaboration.addOutcome(outcomes[1]);
    collaboration.addOutcome(outcomes[2]);

    // Save collaboration and check count.
    db.save(collaboration);
    assertTrue("Check if collaboration found after save.", db.hasCollaboration(id));

    // Retrieve collaboration back and check values.
    MyCollaboration collaboration2 = db.get(id);
    assertEquals("Check ID.", id, collaboration2.getId());
    assertEquals("Check name.", name.trim(), collaboration2.getName());
    assertEquals("Check desc.", desc, collaboration2.getDescription());
    assertEquals("Check org1.", organizations[0], collaboration2.getOrganizations().get(0));
    assertEquals("Check org2.", organizations[1], collaboration2.getOrganizations().get(1));
    assertEquals("Check org3.", organizations[2], collaboration2.getOrganizations().get(2));
    assertEquals("Check year1.", years[0], collaboration2.getYears().get(0));
    assertEquals("Check year2.", years[1], collaboration2.getYears().get(1));
    assertEquals("Check year3.", years[2], collaboration2.getYears().get(2));
    assertEquals("Check type1.", types[0], collaboration2.getTypes().get(0));
    assertEquals("Check type2.", types[1], collaboration2.getTypes().get(1));
    assertEquals("Check type3.", types[2], collaboration2.getTypes().get(2));
    assertEquals("Check outcome1.", outcomes[0], collaboration2.getOutcomes().get(0));
    assertEquals("Check outcome2.", outcomes[1], collaboration2.getOutcomes().get(1));
    assertEquals("Check outcome3.", outcomes[2], collaboration2.getOutcomes().get(2));

    // Test for non-existent collaboration.
    assertFalse("Check non-existant collaboration.", db.hasCollaboration("BAD_ID"));
    assertNull("Check getting non-existant collaboration.", db.get("BAD_ID2"));

    // Test update.
    db.save(collaboration);
    assertTrue("Check if collaboration found after save.", db.hasCollaboration(id));

    // Retrieve collaboration back and check values.
    MyCollaboration collaboration3 = db.get(id);
    assertEquals("Check ID.", id, collaboration3.getId());
    assertEquals("Check name.", name.trim(), collaboration3.getName());
    assertEquals("Check desc.", desc, collaboration3.getDescription());
    assertEquals("Check org1.", organizations[0], collaboration3.getOrganizations().get(0));
    assertEquals("Check org2.", organizations[1], collaboration3.getOrganizations().get(1));
    assertEquals("Check org3.", organizations[2], collaboration3.getOrganizations().get(2));
    assertEquals("Check year1.", years[0], collaboration3.getYears().get(0));
    assertEquals("Check year2.", years[1], collaboration3.getYears().get(1));
    assertEquals("Check year3.", years[2], collaboration3.getYears().get(2));
    assertEquals("Check type1.", types[0], collaboration3.getTypes().get(0));
    assertEquals("Check type2.", types[1], collaboration3.getTypes().get(1));
    assertEquals("Check type3.", types[2], collaboration3.getTypes().get(2));
    assertEquals("Check outcome1.", outcomes[0], collaboration3.getOutcomes().get(0));
    assertEquals("Check outcome2.", outcomes[1], collaboration3.getOutcomes().get(1));
    assertEquals("Check outcome3.", outcomes[2], collaboration3.getOutcomes().get(2));
  }

  /**
   * Test the insert, update, query etc for the collaboration table.
   */
  @Test
  public void testClearDeleteListCount() {
    DatabaseCollaborations db = new DatabaseCollaborations();
    db.clear();

    // Set up test strings.
    String name = "collaboration name ";
    String desc = "Desc";
    String[] organizations = { "Organization1", "Organization2", "Organization3" };
    String[] years = { "2000", "2001", "2002" };
    String[] types = { "Type1", "Type2", "Type3" };
    String[] outcomes = { "Outcome1", "Outcome2", "Outcome3" };

    // Set up record vars.
    MyCollaboration collaboration = new MyCollaboration();
    collaboration.setName(name);
    collaboration.setDescription(desc);
    collaboration.addOrganization(organizations[0]);
    collaboration.addOrganization(organizations[1]);
    collaboration.addOrganization(organizations[2]);
    collaboration.addYear(years[0]);
    collaboration.addYear(years[1]);
    collaboration.addYear(years[2]);
    collaboration.addType(types[0]);
    collaboration.addType(types[1]);
    collaboration.addType(types[2]);
    collaboration.addOutcome(outcomes[0]);
    collaboration.addOutcome(outcomes[1]);
    collaboration.addOutcome(outcomes[2]);

    // Save collaboration and check count.
    Integer expected = 0;
    assertEquals("Check that db is empty.", expected, db.count());
    collaboration.setName("name1");
    db.save(collaboration);
    expected++;
    assertEquals("Check that db has 1 record.", expected, db.count());

    // Save 2nd record
    collaboration.setName("name2");
    db.save(collaboration);
    expected++;
    assertEquals("Check that db has 2 records.", expected, db.count());

    // Save 3rd record
    collaboration.setName("name3");
    db.save(collaboration);
    expected++;
    assertEquals("Check that db has 3 records.", expected, db.count());

    // Check list function
    List<MyCollaboration> results = db.list();
    assertEquals("Check record 1", "NAME1", results.get(0).getId());
    assertEquals("Check record 2", "NAME2", results.get(1).getId());
    assertEquals("Check record 3", "NAME3", results.get(2).getId());

    // Delete 2nd record
    collaboration.setName("name2");
    db.delete("NAME2");
    expected--;
    assertEquals("Check that db has 2 records.", expected, db.count());
    assertFalse("Check that record 2 is gone", db.hasCollaboration("NAME2"));

    db.clear();
    expected = 0;
    assertEquals("Check that db is empty.", expected, db.count());
  }

  /**
   * Drop test tables.
   */
  @After
  public void cleanUpTables() {
    DatabaseCollaborations db = new DatabaseCollaborations();
    db.dropTables();
  }
}
